package cn.mill.core.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.mill.common.Node;
import cn.mill.common.data.Item;
import cn.mill.common.data.ItemArray;
import cn.mill.core.Constants;
import cn.mill.core.MillConfig;

public class NormUtil {
	
	private static Logger logger = LoggerFactory.getLogger(MillConfig.class);
	
	/**
	 * 可直接查找 name.subname.subname 类似规则的 字段数据，越过相关 对象。
	 **/
	public static Item leapfrogSearch(String name, String synonym, ItemArray itemArray) {
		String[] nameArray = name.split(Constants.NAME_SPILT);
		if (nameArray != null && nameArray.length > 1 && nameArray.length <= 2) {
			ItemArray tempArray = itemArray;
			for (String nkey : nameArray) {
				Item item = tempArray.search(nkey, synonym);
				if (item != null && item.getValue() != null && item.getValue() instanceof ItemArray) {
					tempArray = (ItemArray) item.getValue();
					tempArray.sort();
				} else {
					return item;
				}
			}
			return null;
		}
		return itemArray.search(name, synonym);
	}
	
	public static String getUri(Node node, String path) {
		if (Constants.FILE_PROTOCOL.equals(node.protocol())) {
			return node.protocol() + "://" + node.path() + (NormUtil.isNotEmpty(path) ? path : "");
		} else {
			return node.protocol() + "://" + node.host() + (node.port() > 0 ? (":" + node.port()) : "") + node.path() + (NormUtil.isNotEmpty(path) ? path : "");
		}
	}
	
	public static String readStream(InputStream io) {
		BufferedReader reader;
		StringBuilder sb = new StringBuilder();
		try {
			reader = new BufferedReader(new InputStreamReader(io, "UTF-8"));
			String s; // 依次循环，至到读的值为空
			while ((s = reader.readLine()) != null) {
				sb.append(s);
			}
			reader.close();
		} catch (Exception e) {
			logger.error("NormUtil readStream", e);
		}
		return sb.toString();
	}
	
	public static String placeHolder(String str, Map<String, Item> attachments) {
		Pattern p = Pattern.compile("(\\{)([\\w]+)(\\})");
		Matcher m = p.matcher(str);
		StringBuffer sb = new StringBuffer();
		while (m.find()) {
			String group = m.group(2);// 规则中${值}中的 值 一样 的数据不
			Item i = attachments.get(group);
			// 下一步是替换并且把替换好的值放到sb中
			if (i != null) {
				m.appendReplacement(sb, (String) (i.getValue() + ""));
			} else {
				m.appendReplacement(sb, "");
			}
		}
		m.appendTail(sb);
		return sb.toString();
	}
	
	public static Item ItemBuilder(String name, Type type, Object value) {
		return new Item(null, name, type, value);
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> T createJavaObject(Type type) {
		try {
			if (type instanceof ParameterizedType) {
				Type rawType = ((ParameterizedType) type).getRawType();
				// Type[] params = ((ParameterizedType)
				// type).getActualTypeArguments();
				// Class<T> subClazz = (Class) params[0] ;
				return (T) ((Class) rawType).newInstance();
			} else if (type instanceof WildcardType || type == void.class) {
				return null;
			} else {
				Class c = (Class) type;
				Object o = c.newInstance();
				return (T) o;
			}
		} catch (Exception e) {
			logger.error("---->", e);
			return null;
		}
	}
	
	public static boolean isTypeVariable(Type type) {
		if (type instanceof ParameterizedType) {
			Type[] ts = ((ParameterizedType) type).getActualTypeArguments();
			for (Type t : ts) {
				if (t instanceof TypeVariable) {
					return true;
				}
			}
		}
		return false;
	}
	
	public static Type getType(Type classType, Type filedType) {
		if (NormUtil.isTypeVariable(filedType)) {
			Type[] actualTypeArguments = NormUtil.getActualType(classType);
			ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(actualTypeArguments, NormUtil.getOwnerType(filedType), NormUtil.getRawType(filedType));
			return parameterizedType;
		}
		return filedType;
	}
	
	/**
	 * 
	 * @Title: getRawType
	 * @Description:
	 * @param type
	 * @return Type 返回类型
	 */
	public static Type getRawType(Type type) {
		if (type instanceof ParameterizedType) {
			return ((ParameterizedType) type).getRawType();
		}
		return null;
	}
	
	public static Type getOwnerType(Type type) {
		if (type instanceof ParameterizedType) {
			return ((ParameterizedType) type).getOwnerType();
		}
		return null;
	}
	
	public static Type[] getActualType(Type type) {
		if (type instanceof ParameterizedType) {
			return ((ParameterizedType) type).getActualTypeArguments();
		}
		return null;
	}
	
	public static Annotation[] getParameterAnnotations(int order, Annotation[][] pann) {
		if (pann == null || order < 0 || order >= pann.length) {
			return null;
		}
		return pann[order];
	}
	
	public static Annotation getAnnotation(Class<?> annotationClass, Annotation[] arr) {
		if (annotationClass == null || arr == null) {
			return null;
		}
		for (Annotation a : arr) {
			if (annotationClass.isAnnotation() && a.annotationType().equals(annotationClass)) {
				return a;
			}
		}
		return null;
	}
	
	public static boolean isBaseObject(Object object) {
		if (object == null) {
			return false;
		}
		if (object instanceof String) {
			return true;
		} else if (object instanceof Number) {
			return true;
		} else if (object instanceof Character) {
			return true;
		} else if (object instanceof Boolean) {
			return true;
		} else if (object instanceof java.util.Date) {
			return true;
		} else if (object instanceof java.sql.Date) {
			return true;
		}
		return false;
	}
	
	public static Field[] getJavaBeanField(Object javaBean) {
		if (javaBean != null) {
			return javaBean.getClass().getDeclaredFields();
		} else {
			return null;
		}
	}
	
	public static boolean isEmpty(String str) {
		return str == null || str.isEmpty();
	}
	
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}
	
	public static String format() {
		return "";
	}
}
